docker deploy provider: work when core runs in a container - #858
Open
irisfeng wants to merge 1 commit into
Open
Conversation
The docker deploy provider assumed core runs on the host: it
bind-mounted the snapshot directory (a path inside core's container,
resolved by the host daemon against the host filesystem — an
auto-created empty dir, so every published app died on MODULE_NOT_FOUND)
and returned 127.0.0.1 endpoints (host loopback, which a containerized
core cannot reach).
Materialize snapshots with docker create + docker cp + docker start
instead: docker cp streams through the daemon API from wherever the
docker CLI runs, so no filesystem boundary is crossed. The copy gets a
generous timeout — snapshots routinely carry node_modules and the
default exec timeout would kill large copies mid-stream.
Add a shared-network mode: when DEPLOY_DOCKER_NETWORK names the network
core already sits on, each app container joins that network with a
network-alias equal to its container name and the endpoint becomes
{host: <container-name>, port: APP_PORT} — resolvable through docker's
embedded DNS, no host port publishing. qm up sets the variable for core
next to DOCKER_HOST/QM_CORE_CONTAINER, extracted into one shared
helper so the serviceEnv and dockerServiceEnv code paths cannot drift
apart again. Deployments stored with a pre-fix loopback endpoint
resolve as absent so the service re-materializes them onto the shared
network. Without the variable the provider keeps the previous
per-deployment network + published loopback port shape for host-run
core.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
qm upon the docker backend runs every service — including core — as a container on one shared stack network, with core's/dataas a named volume and (when the local sandbox backend is active) the docker CLI plusDOCKER_HOST/QM_CORE_CONTAINERwired into core. That is the shape self-hosted deployments get out of the box, and the docker deploy provider (the defaultDEPLOY_PROVIDER) assumes the opposite of it in two places:applyran the app container with-v ${snapshotDir}:/app:ro. The snapshot lives inside core's container/volume; the host daemon resolves that path against the host filesystem and auto-creates an empty directory there — every published app starts with no code and dies onMODULE_NOT_FOUND. Verified on a live deployment: the host-side directory is empty, the core-container-side one has the app.applypublished the app port on127.0.0.1and returned{host: "127.0.0.1"}. A containerized core dialing loopback reaches itself, never the app — so even a running app was unreachable.Fix
docker create→docker cp <snapshotDir>/. <container>:/app→docker start.docker cpstreams through the daemon API from wherever the docker CLI runs, so no filesystem boundary is crossed — correct for container-run and host-run core. The copy gets a generous explicit timeout (snapshots routinely carrynode_modules; the 60s default would kill large copies mid-stream).DEPLOY_DOCKER_NETWORKenv names the network core already sits on.qm upsets it for core alongsideDOCKER_HOST/QM_CORE_CONTAINER— those three now come from one shared helper so theserviceEnvanddockerServiceEnvcode paths cannot drift apart again. Each app container joins that network with--network-alias <container-name>and no host port publishing; the endpoint becomes{host: <container-name>, port: APP_PORT}, resolved through docker's embedded DNS.destroynever removes a network it did not create. Deployments stored with a pre-fix loopback endpoint resolve as absent so the deploy service re-materializes them onto the shared network.DEPLOY_DOCKER_NETWORK, the provider keeps the previous per-deployment network + published loopback port shape, which is correct for core running directly on the host.Endpoint consumers already treat
hostas an opaque hostname (the proxy dialshost:portfrom core), so no consumer changes were needed.Tests
Provider: shared-mode sequence (create → cp → start, no
-v/-p, alias endpoint, network untouched on destroy), copy-failure and start-failure cleanup, stale-loopback re-materialization, plus new pins on the fallback path (loopback publish + snapshot copy). CLI: the existing "host daemon coordinates only into core" test now also pinsDEPLOY_DOCKER_NETWORK. Full provider suite 9/9, auth-broker 11/11, CLI suite identical to the pre-change baseline (same env-gated failures).Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.